#include "bsp_i2c.h"


/*
 * DEFINES
 *****************************************************************************************
 */
#define MASTER_I2C_ID           APP_I2C_MASTER_ID
#define SLAVE_DEV_ADDR          0x0E

app_i2c_params_t master_params = {
    .id = MASTER_I2C_ID,
    .role = APP_I2C_ROLE_MASTER,
    .pin_cfg = {
        .scl = {
            .type = APP_I2C_MASTER_SCL_IO_TYPE,
            .mux  = APP_I2C_MASTER_SCL_PINMUX,
            .pin  = APP_I2C_MASTER_SCL_PIN,
            .pull = APP_IO_PULLUP,
        },
        .sda = {
            .type = APP_I2C_MASTER_SDA_IO_TYPE,
            .mux  = APP_I2C_MASTER_SDA_PINMUX,
            .pin  = APP_I2C_MASTER_SDA_PIN,
            .pull = APP_IO_PULLUP,
        },
    },
    .dma_cfg = {
        .tx_dma_instance = DMA0,
        .rx_dma_instance = DMA0,
        .tx_dma_channel  = DMA_Channel2,
        .rx_dma_channel  = DMA_Channel3,
    },
    .init = {
        .speed = I2C_SPEED_400K,
        .own_address = 0x00,
        .addressing_mode = I2C_ADDRESSINGMODE_7BIT,
        .general_call_mode = I2C_GENERALCALL_DISABLE,
    },
};


/*
 * GLOBAL VARIABLE DEFINITIONS
 *****************************************************************************************
 */
volatile uint8_t g_master_tdone = 0;
volatile uint8_t g_master_rdone = 0;

/*
 * LOCAL FUNCTION DEFINITIONS
 *****************************************************************************************
 */
static void app_i2c_master_evt_handler(app_i2c_evt_t * p_evt)
{
    switch (p_evt->type)
    {
        case APP_I2C_EVT_ERROR:
            g_master_tdone = 1;
            g_master_rdone = 1;
            break;

        case APP_I2C_EVT_TX_CPLT:
            g_master_tdone = 1;
            break;

        case APP_I2C_EVT_RX_DATA:
            g_master_rdone = 1;
            break;
    }
}

/*
 * GLOBAL FUNCTION DEFINITIONS
 ****************************************************************************************
 */
void app_i2c_master_interrupt(void)
{
    uint32_t i;
    uint16_t ret = 0;
    uint8_t  wdata[256] = {0};
    uint8_t  rdata[256] = {0};

    ret = app_i2c_init(&master_params, app_i2c_master_evt_handler);
    if (ret != 0)
    {
        GR_LOG("\r\nI2C master initial failed! Please check the input parameters.\r\n");
        return;
    }
    for(i = 0; i < 256; i++)
    {
        wdata[i] = i;
        rdata[i] = 0;
    }

    GR_LOG("I2C master send start.\r\n");
    delay_ms(1000); /*****wait for slave ready*****/
    g_master_tdone = 0;
    ret = app_i2c_transmit_async(MASTER_I2C_ID, SLAVE_DEV_ADDR, wdata, 256);
    if (ret != APP_DRV_SUCCESS)
    {
        GR_LOG("I2C master send failed.\r\n");
        return;
    }
    while(g_master_tdone == 0);

    memset(rdata, 0, sizeof(rdata));
    delay_ms(1000); /*****wait for slave ready*****/
    GR_LOG("I2C master read start.\r\n");
    g_master_rdone = 0;
    ret = app_i2c_receive_async(MASTER_I2C_ID, SLAVE_DEV_ADDR, rdata, 256);
    if (ret != APP_DRV_SUCCESS)
    {
        GR_LOG("I2C master receive failed.\r\n");
        return;
    }
    while(g_master_rdone == 0);

    GR_LOG("I2C master received:\r\n");
    for (i = 0; i < 256; i++)
    {
        GR_LOG("0x%02X ", rdata[i]);
        if ((i & 0x7) == 0x7)
            GR_LOG("\r\n");
    }
    GR_LOG("\r\n");

    app_i2c_deinit(MASTER_I2C_ID);
}




int user_i2c_init(void)
{
    uint16_t ret = 0;

    ret = app_i2c_init(&master_params, app_i2c_master_evt_handler);
    if (ret != 0)
    {
        GR_LOG("\r\n I2C master initial failed! Please check the input parameters.\r\n");
        return 1;
    }
    return 0;
}

int user_i2c_deinit(void)
{
//    hal_i2c_deinit(&g_i2c_handle);
    app_i2c_deinit(master_params.id);
	
	gpio_init_t gpio_config = GPIO_DEFAULT_CONFIG;

	gpio_config.mode = GPIO_MODE_MUX;
	gpio_config.mux  = GPIO_MUX_7;
	gpio_config.pull = GPIO_NOPULL;
	gpio_config.pin  = GPIO_PIN_14 | GPIO_PIN_10;
	hal_gpio_init(GPIO1, &gpio_config);
    
    return 0;
}

int user_i2c_trans_recv(uint8_t devAddr, uint8_t *pW, int wLen, uint8_t *pRecv, int reavLen)
{
    int ret = 0;

    if((NULL != pW) && (0 < wLen))
    {
        g_master_tdone = 0;
        ret = app_i2c_transmit_async(MASTER_I2C_ID, devAddr, pW, wLen);
        if (ret != APP_DRV_SUCCESS)
        {
            return 1;
        }
        while(g_master_tdone == 0);
    }
    
    if((NULL != pRecv) && (0 < reavLen))
    {
        g_master_rdone = 0;
        ret = app_i2c_receive_async(MASTER_I2C_ID, devAddr, pRecv, reavLen);
        if (ret != APP_DRV_SUCCESS)
        {
            return ret;
        }
        while(g_master_rdone == 0);
    }
    
    return 0;
}


